package org.light.shiroauth;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.light.core.LayoutComb;
import org.light.core.ReportComb;
import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.ManyToMany;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Util;
import org.light.easyuilayouts.widgets.Nav;
import org.light.utils.DomainUtil;
import org.light.utils.StringUtil;

public class MySessionManagerJavaGenerator extends Util{
	protected Domain userDomain;
	protected Domain roleDomain;
	protected Domain privilegeDomain;
	protected Nav nav;
	
	public MySessionManagerJavaGenerator(){
		super();
		super.fileName = "MySessionManager.java";
	}
	
	public MySessionManagerJavaGenerator(String packageToken){
		super();
		this.setPackageToken(packageToken);
		super.fileName = "MySessionManager.java";
	}
	
	@Override
	public void setPackageToken(String packageToken) {
		this.packageToken = packageToken;
	}
	
	@Override
	public String generateUtilString() {
		StatementList sList = new StatementList();
		sList.add(new Statement(500L,"package "+this.getPackageToken()+".shiro;"));
		sList.add(new Statement(2000L,0,""));

		sList.add(new Statement(3000L,0,"import java.io.Serializable;"));
		sList.add(new Statement(4000L,0,"import java.util.Enumeration;"));
		sList.add(new Statement(5000L,0,""));
		sList.add(new Statement(6000L,0,"import javax.servlet.ServletRequest;"));
		sList.add(new Statement(7000L,0,"import javax.servlet.ServletResponse;"));
		sList.add(new Statement(8000L,0,"import javax.servlet.http.Cookie;"));
		sList.add(new Statement(9000L,0,""));
		sList.add(new Statement(10000L,0,"import org.apache.commons.lang3.StringUtils;"));
		sList.add(new Statement(11000L,0,"import org.apache.shiro.web.servlet.ShiroHttpServletRequest;"));
		sList.add(new Statement(12000L,0,"import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;"));
		sList.add(new Statement(13000L,0,"import org.apache.shiro.web.util.WebUtils;"));
		sList.add(new Statement(14000L,0,""));
		sList.add(new Statement(15000L,0,"import "+this.getPackageToken()+".utils.StringUtil;"));
		sList.add(new Statement(16000L,0,""));
		sList.add(new Statement(17000L,0,"/**"));
		sList.add(new Statement(18000L,0,"* @author by. 不笑猫丶"));
		sList.add(new Statement(19000L,0,"* @date 2018年12月12日"));
		sList.add(new Statement(20000L,0,"* 自定义session获取"));
		sList.add(new Statement(21000L,0,"*/"));
		sList.add(new Statement(22000L,0,"public class MySessionManager  extends DefaultWebSessionManager {"));
		sList.add(new Statement(23000L,0,""));
		sList.add(new Statement(24000L,1,"//private static final Logger logger = LoggerFactory.getLogger(MySessionManager.class);"));
		sList.add(new Statement(25000L,0,""));
		sList.add(new Statement(26000L,1,"private static final String AUTHORIZATION = \"Authorization\";"));
		sList.add(new Statement(27000L,0,""));
		sList.add(new Statement(28000L,1,"private static final String REFERENCED_SESSION_ID_SOURCE = \"Stateless request\";"));
		sList.add(new Statement(29000L,0,""));
		sList.add(new Statement(30000L,1,"public MySessionManager() {"));
		sList.add(new Statement(31000L,2,"super();"));
		sList.add(new Statement(32000L,1,"}"));
		sList.add(new Statement(33000L,1,""));
		sList.add(new Statement(34000L,1,"public String getQuerySessionId(String queryString) {"));
		sList.add(new Statement(35000L,2,"if (!StringUtil.isBlank(queryString)) {"));
		sList.add(new Statement(36000L,3,"String[] mytokens;"));
		sList.add(new Statement(37000L,3,"if (queryString.contains(\"&\")) {"));
		sList.add(new Statement(38000L,4,"mytokens = queryString.split(\"&\");"));
		sList.add(new Statement(39000L,3,"}else {"));
		sList.add(new Statement(40000L,4,"mytokens = new String [1];"));
		sList.add(new Statement(41000L,4,"mytokens[0] = queryString;"));
		sList.add(new Statement(42000L,3,"}"));
		sList.add(new Statement(43000L,3,"if (mytokens!=null) {"));
		sList.add(new Statement(44000L,4,"for (int i = 0; i < mytokens.length; i++) {"));
		sList.add(new Statement(45000L,5,"if (mytokens[i].contains(\"token\")) {"));
		sList.add(new Statement(46000L,6,"String[] tokens = mytokens[i].split(\"=\");"));
		sList.add(new Statement(47000L,6,"return tokens[1];"));
		sList.add(new Statement(48000L,5,"}"));
		sList.add(new Statement(49000L,4,"}"));
		sList.add(new Statement(50000L,3,"}"));
		sList.add(new Statement(51000L,2,"}"));
		sList.add(new Statement(52000L,2,"return \"\";"));
		sList.add(new Statement(53000L,1,"}"));
		sList.add(new Statement(54000L,0,""));
		sList.add(new Statement(55000L,1,"@Override"));
		sList.add(new Statement(56000L,1,"protected Serializable getSessionId(ServletRequest request, ServletResponse response) {"));
		sList.add(new Statement(57000L,2,"//String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);"));
		sList.add(new Statement(58000L,2,"String qstr = WebUtils.toHttp(request).getQueryString();"));
		sList.add(new Statement(59000L,2,"String id =  getQuerySessionId(qstr);"));
		sList.add(new Statement(60000L,2,""));
		sList.add(new Statement(61000L,0,"//        Enumeration<String> xToken = WebUtils.toHttp(request).getHeaderNames();"));
		sList.add(new Statement(62000L,0,"//"));
		sList.add(new Statement(63000L,0,"//        while( xToken.hasMoreElements()) {"));
		sList.add(new Statement(64000L,0,"//        	String str = xToken.nextElement();"));
		sList.add(new Statement(65000L,0,"//        	System.out.println(str);"));
		sList.add(new Statement(66000L,0,"//        	System.out.println(WebUtils.toHttp(request).getHeader(str));"));
		sList.add(new Statement(67000L,0,"//        }"));
		sList.add(new Statement(68000L,0,"//"));
		sList.add(new Statement(69000L,0,"//        Cookie [] cookies = WebUtils.toHttp(request).getCookies();"));
		sList.add(new Statement(70000L,0,"//        if (cookies!=null) {"));
		sList.add(new Statement(71000L,0,"//	        for (Cookie c:cookies) {"));
		sList.add(new Statement(72000L,0,"//	        	System.out.println(c.getName()+\":cookie:\"+c.getValue());"));
		sList.add(new Statement(73000L,0,"//	        }"));
		sList.add(new Statement(74000L,0,"//        }"));
		sList.add(new Statement(75000L,0,""));
		sList.add(new Statement(76000L,2,"String myToken = WebUtils.toHttp(request).getHeader(\"X-Token\");"));
		sList.add(new Statement(77000L,2,"if (!StringUtil.isBlank(myToken)) id = myToken;"));
		sList.add(new Statement(78000L,2,"//if (!StringUtil.isBlank(xToken)) id = xToken;"));
		sList.add(new Statement(79000L,2,"//如果请求头中有 Authorization 则其值为sessionId"));
		sList.add(new Statement(80000L,2,"if (!StringUtils.isEmpty(id)) {"));
		sList.add(new Statement(81000L,3,"request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);"));
		sList.add(new Statement(82000L,3,"request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);"));
		sList.add(new Statement(83000L,3,"request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);"));
		sList.add(new Statement(84000L,2,"// logger.info(\"Session管理器检测到AUTHORIZATION token 使用此token作为Session\");"));
		sList.add(new Statement(85000L,3,"return id;"));
		sList.add(new Statement(86000L,2,"} else {"));
		sList.add(new Statement(87000L,3,"//否则按默认规则从cookie取sessionId"));
		sList.add(new Statement(88000L,3,"return super.getSessionId(request, response);"));
		sList.add(new Statement(89000L,2,"}"));
		sList.add(new Statement(90000L,1,"}"));
		sList.add(new Statement(91000L,0,"}"));
		
		return sList.getContent();
	}

	public Domain getUserDomain() {
		return userDomain;
	}

	public void setUserDomain(Domain userDomain) {
		this.userDomain = userDomain;
	}

	public Domain getRoleDomain() {
		return roleDomain;
	}

	public void setRoleDomain(Domain roleDomain) {
		this.roleDomain = roleDomain;
	}

	public Domain getPrivilegeDomain() {
		return privilegeDomain;
	}

	public void setPrivilegeDomain(Domain privilegeDomain) {
		this.privilegeDomain = privilegeDomain;
	}

	public Nav getNav() {
		return nav;
	}

	public void setNav(Nav nav) {
		this.nav = nav;
	}

	
	public String getTranslateRefers(Set<Domain> targets,Domain domain) {
		Map<Domain,Set<Domain>> tanslateReferMap = new TreeMap<>();
		for (Domain target:targets) {
			for (Field f: target.getFields()) {
				if (f instanceof Dropdown) {
					Dropdown dp = (Dropdown)f;
					if (!target.getStandardName().equals(dp.getTarget())) {
						Set<Domain> refers = tanslateReferMap.get(dp.getTarget());
						if (refers == null) refers= new TreeSet<Domain>();					
						refers.add(target);
						tanslateReferMap.put(dp.getTarget(), refers);	
					}
				}
			}
		}
		Set<Domain> retVal = tanslateReferMap.get(domain);
		String retstr = "";
		if (retVal!=null) {
			retVal.remove(domain);
			for (Domain d:retVal) {
				retstr = retstr + d.getStandardName()+",";
			}
		}
		if (retstr.contains(",")) retstr = retstr.substring(0,retstr.length()-1);
		return retstr;
	}

}
